#include "GL/glew.h"
#include "LoadShader.h"
#include "utility.h"
#include "vmath.h"
#include "loadDDSTexture.h"
#include "GLFW/glfw3.h"

extern int Width, Height;

GLuint tex2D, texCube;

GLuint program2D, programCube;
Model3D panel, cube;

float roateX=0, roateY =0;
bool IsleftButtonDown = false;

void mousePositionCallback(GLFWwindow* window, double xpos, double ypos)
{
	static double preX, preY;
	double delaX = 0, delaY = 0;
	if (IsleftButtonDown)
	{
		delaX = xpos - preX;
		delaY = ypos - preY;
		roateX += (float)delaX;
		roateY += (float)delaY;
	}

	preX = xpos;
	preY = ypos;
}

void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
{
	if (button == GLFW_MOUSE_BUTTON_LEFT)
	{
		IsleftButtonDown = action == GLFW_PRESS;
	}
}

bool init()
{
	float texData[] = { 1.0, 0.0, 0.0, 1.0,
						0.0, 1.0, 0.0, 1.0,
						0.0, 0.0, 1.0, 1.0,
						1.0, 1.0 ,1.0, 1.0 };

	vglImageData image;
	vglLoadImage("image.dds", &image);

	tex2D = vglLoadTexture(&image);
	glBindTexture(GL_TEXTURE_2D, texCube);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	vglUnloadImage(&image);

	const char *files[6] = {"imageX1.dds","imageX2.dds", "imageY1.dds", "imageY2.dds", "imageZ1.dds", "imageZ2.dds"};
	glGenTextures(1, &texCube);
	glBindTexture(GL_TEXTURE_CUBE_MAP, texCube);
	for (int i = 0; i < 6; ++i)
	{
		vglLoadImage(files[i], &image);
		vglImageMipData *pMip = image.mip;
		glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, image.internalFormat, pMip->width, pMip->height, 0, image.format, image.type, pMip->data);
		vglUnloadImage(&image);
	}
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);


	ShaderInfo si2[] = { { GL_VERTEX_SHADER, "Texture2D.vert" },{ GL_FRAGMENT_SHADER, "Texture2D.frag" },{ GL_NONE, nullptr } };
	program2D = LoadShade(si2);

	ShaderInfo si3[] = { { GL_VERTEX_SHADER, "Cube.vert" },{ GL_FRAGMENT_SHADER, "Cube.frag" },{ GL_NONE, nullptr } };
	programCube = LoadShade(si3);

	panel = LoadPanel(0, -1, 1);
	cube = LoadCube(0, -1);


	glClearColor(0.0f, 0.05f, 0.05f, 1.0f);
	return true;
}

void Display(double time)
{
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glEnable(GL_DEPTH_TEST);

	glUseProgram(program2D);
	auto m = Matrix4f::createScale(0.003f, 0.003f*Width / Height, 0.0f);
	m = Matrix4f::createTranslation(-0.5f, 0.f, 0.f) * m;
	glUniformMatrix4fv(0, 1, GL_FALSE, m);
	glUniform1i(1, 0);
	glBindTexture(GL_TEXTURE_2D, tex2D);
	panel.Draw();
	glBindTexture(GL_TEXTURE_2D, 0);

	glUseProgram(programCube);

	m = Matrix4f::createRotationAroundAxis(-roateY, -roateX, 0);
	m = Matrix4f::createTranslation(0.0f, 0.f, -500.f) *m;
	m = Matrix4f::createFrustum(-5, 5, -5.f*Height / Width, 5.f*Height / Width, 5, 1000) * m;
	m = Matrix4f::createTranslation(0.5f, 0.f, 0.f) * m;

	glUniformMatrix4fv(0, 1, GL_FALSE, m);
	glUniform1i(1, 0);
	glBindTexture(GL_TEXTURE_CUBE_MAP, texCube);
	cube.Draw();
	glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
}

void onClose()
{
	panel.deleteBuffer();
}

